module.exports = (options, app) => {
  return async (ctx, next) => {
    // 1.获取token
    const token = ctx.header.authorization || ctx.query.token
    // 2.是否有token
    if (!token) ctx.throw(401, '您没有权限访问该接口！')
    // 3.解密token,获取用户信息
    let user = {}
    let newToken = '' // 新token
    let userToken = '' // 用户登录状态
    try {
      user = ctx.verifyToken(token)
    } catch (error) {
      // 短token过期
      if (error.name === 'TokenExpiredError') {
        try {
          const userAccess = ctx.verifyToken(token, true)
          // 查询用户是否登录了
          userToken = await app.redis.get(`user:${userAccess.id}`)
          if (!userToken) ctx.throw(401, '登录过期，请重新登录')
          userToken = JSON.parse(userToken)
          // 验证refreshToken 获取用户id
          user = ctx.verifyToken(userToken.refreshToken)
          // 验证成功，创建新token
          newToken = await ctx.service.user.createNewToken({ id: user.id })
        } catch (error) {
          const fail =
            error.name === 'TokenExpiredError' ? '登录过期，请重新登录' : 'Token令牌不合法'
          ctx.throw(401, fail)
        }
      } else {
        ctx.throw(401, 'Token令牌不合法')
      }
    }
    // 判断用户是否登录了
    if (!userToken) {
      userToken = await app.redis.get(`user:${user.id}`)
      if (!userToken) ctx.throw(401, '登录过期，请重新登录')
    }
    // 4.获取当前用户，验证用户是否被禁用
    user = await ctx.service.user.findById(user.id)
    if (!user || user.status === 2) {
      ctx.throw(401, '用户不存在或已被禁用！')
    }
    // 5.把用户信息挂载到ctx
    ctx.authUser = user.toJSON()
    // 6.继续执行
    await next()
    // 判断是否有新token，设置响应头
    if (newToken) {
      ctx.set('Token', newToken)
      ctx.set('Access-Control-Expose-Headers', 'Token')
    }
  }
}
